/**
 * 消息模型
 * PC微信聊天应用 - 消息数据操作
 */

const { db } = require('../config/database');

class Message {
  /**
   * 创建新消息
   * @param {Object} messageData 消息数据
   * @returns {Promise<number>} 消息ID
   */
  static async create(messageData) {
    try {
      const {
        conversationId,
        fromUserId,
        toUserId,
        content,
        type = 'text',
        fileUrl,
        fileName,
        fileSize,
        fileType
      } = messageData;

      const sql = `
        INSERT INTO messages (
          conversation_id, from_user_id, to_user_id, content, type,
          file_url, file_name, file_size, file_type
        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
      `;

      const result = await db.query(sql, [
        conversationId, fromUserId, toUserId, content, type,
        fileUrl || null, fileName || null, fileSize || null, fileType || null
      ]);

      return result.insertId;
    } catch (error) {
      console.error('创建消息错误:', error);
      throw error;
    }
  }

  /**
   * 获取会话消息历史
   * @param {number} conversationId 会话ID
   * @param {number} limit 限制数量
   * @param {number} offset 偏移量
   * @returns {Promise<Array>} 消息列表
   */
  static async getConversationMessages(conversationId, limit = 50, offset = 0) {
    try {
      console.log('获取会话消息，参数:', { conversationId, limit, offset })

      // 确保参数类型正确
      const safeConversationId = parseInt(conversationId)
      const safeLimit = parseInt(limit)
      const safeOffset = parseInt(offset)

      console.log('安全参数:', { safeConversationId, safeLimit, safeOffset })

      // MySQL的LIMIT和OFFSET不能使用参数绑定，需要直接拼接
      const sql = `
        SELECT
          m.id, m.conversation_id, m.from_user_id, m.to_user_id,
          m.content, m.type, m.file_url, m.file_name, m.file_size, m.file_type,
          m.is_recalled, m.recalled_at, m.created_at,
          u.nickname as sender_nickname, u.icon as sender_icon
        FROM messages m
        LEFT JOIN users u ON m.from_user_id = u.id
        WHERE m.conversation_id = ? AND m.is_recalled = 0
        ORDER BY m.created_at DESC
        LIMIT ${safeLimit} OFFSET ${safeOffset}
      `;

      const messages = await db.query(sql, [safeConversationId]);
      console.log('查询到消息数量:', messages.length)
      return messages.reverse(); // 按时间正序返回
    } catch (error) {
      console.error('获取会话消息错误:', error);
      return [] // 返回空数组而不是抛出错误
    }
  }

  /**
   * 获取私聊消息历史
   * @param {number} userId1 用户1 ID
   * @param {number} userId2 用户2 ID
   * @param {number} limit 限制数量
   * @param {number} offset 偏移量
   * @returns {Promise<Array>} 消息列表
   */
  static async getPrivateMessages(userId1, userId2, limit = 50, offset = 0) {
    try {
      // 首先获取或创建会话
      const conversationId = await this.getOrCreatePrivateConversation(userId1, userId2);
      return await this.getConversationMessages(conversationId, limit, offset);
    } catch (error) {
      console.error('获取私聊消息错误:', error);
      throw error;
    }
  }

  /**
   * 获取或创建私聊会话
   * @param {number} userId1 用户1 ID
   * @param {number} userId2 用户2 ID
   * @returns {Promise<number>} 会话ID
   */
  static async getOrCreatePrivateConversation(userId1, userId2) {
    try {
      console.log('查找或创建会话，用户:', userId1, '和', userId2)

      // 简化查找逻辑，先查找现有会话
      const findSql = `
        SELECT c.id
        FROM conversations c
        JOIN conversation_participants cp1 ON c.id = cp1.conversation_id
        JOIN conversation_participants cp2 ON c.id = cp2.conversation_id
        WHERE c.type = 'private'
        AND ((cp1.user_id = ? AND cp2.user_id = ?) OR (cp1.user_id = ? AND cp2.user_id = ?))
        AND cp1.left_at IS NULL AND cp2.left_at IS NULL
        LIMIT 1
      `;

      const conversations = await db.query(findSql, [userId1, userId2, userId2, userId1]);

      if (conversations.length > 0) {
        console.log('找到现有会话:', conversations[0].id)
        return conversations[0].id;
      }

      console.log('创建新会话...')

      // 创建新会话 - 简化版本，不使用事务
      const createConversationSql = 'INSERT INTO conversations (type, created_by) VALUES (?, ?)';
      const conversationResult = await db.query(createConversationSql, ['private', userId1]);
      const conversationId = conversationResult.insertId;

      console.log('创建会话成功，ID:', conversationId)

      // 添加参与者
      const addParticipantSql = 'INSERT INTO conversation_participants (conversation_id, user_id) VALUES (?, ?)';
      await db.query(addParticipantSql, [conversationId, userId1]);
      await db.query(addParticipantSql, [conversationId, userId2]);

      console.log('添加参与者成功')

      return conversationId;
    } catch (error) {
      console.error('获取或创建私聊会话错误:', error);
      throw error;
    }
  }

  /**
   * 搜索消息
   * @param {number} userId 用户ID
   * @param {string} keyword 搜索关键词
   * @param {number} limit 限制数量
   * @returns {Promise<Array>} 搜索结果
   */
  static async search(userId, keyword, limit = 20) {
    try {
      const sql = `
        SELECT 
          m.id, m.conversation_id, m.from_user_id, m.to_user_id,
          m.content, m.type, m.created_at,
          u.nickname as sender_nickname, u.icon as sender_icon,
          u2.nickname as receiver_nickname
        FROM messages m
        LEFT JOIN users u ON m.from_user_id = u.id
        LEFT JOIN users u2 ON m.to_user_id = u2.id
        JOIN conversation_participants cp ON m.conversation_id = cp.conversation_id
        WHERE cp.user_id = ? 
        AND cp.left_at IS NULL
        AND m.is_recalled = 0
        AND MATCH(m.content) AGAINST(? IN NATURAL LANGUAGE MODE)
        ORDER BY m.created_at DESC
        LIMIT ?
      `;
      
      return await db.query(sql, [userId, keyword, limit]);
    } catch (error) {
      console.error('搜索消息错误:', error);
      throw error;
    }
  }

  /**
   * 标记消息为已读
   * @param {number} messageId 消息ID
   * @param {number} userId 用户ID
   * @returns {Promise<boolean>} 操作结果
   */
  static async markAsRead(messageId, userId) {
    try {
      const sql = `
        INSERT IGNORE INTO message_reads (message_id, user_id)
        VALUES (?, ?)
      `;
      
      const result = await db.query(sql, [messageId, userId]);
      return result.affectedRows > 0;
    } catch (error) {
      console.error('标记消息已读错误:', error);
      throw error;
    }
  }

  /**
   * 批量标记消息为已读
   * @param {number} conversationId 会话ID
   * @param {number} userId 用户ID
   * @returns {Promise<boolean>} 操作结果
   */
  static async markConversationAsRead(conversationId, userId) {
    try {
      const sql = `
        INSERT IGNORE INTO message_reads (message_id, user_id)
        SELECT m.id, ?
        FROM messages m
        WHERE m.conversation_id = ? 
        AND m.from_user_id != ?
        AND m.is_recalled = 0
        AND NOT EXISTS (
          SELECT 1 FROM message_reads mr 
          WHERE mr.message_id = m.id AND mr.user_id = ?
        )
      `;
      
      const result = await db.query(sql, [userId, conversationId, userId, userId]);
      return result.affectedRows > 0;
    } catch (error) {
      console.error('批量标记消息已读错误:', error);
      throw error;
    }
  }

  /**
   * 获取未读消息数量
   * @param {number} userId 用户ID
   * @param {number} conversationId 会话ID（可选）
   * @returns {Promise<number>} 未读消息数量
   */
  static async getUnreadCount(userId, conversationId = null) {
    try {
      let sql, params;
      
      if (conversationId) {
        sql = `
          SELECT COUNT(*) as count
          FROM messages m
          WHERE m.conversation_id = ?
          AND m.from_user_id != ?
          AND m.is_recalled = 0
          AND NOT EXISTS (
            SELECT 1 FROM message_reads mr 
            WHERE mr.message_id = m.id AND mr.user_id = ?
          )
        `;
        params = [conversationId, userId, userId];
      } else {
        sql = `
          SELECT COUNT(*) as count
          FROM messages m
          JOIN conversation_participants cp ON m.conversation_id = cp.conversation_id
          WHERE cp.user_id = ?
          AND cp.left_at IS NULL
          AND m.from_user_id != ?
          AND m.is_recalled = 0
          AND NOT EXISTS (
            SELECT 1 FROM message_reads mr 
            WHERE mr.message_id = m.id AND mr.user_id = ?
          )
        `;
        params = [userId, userId, userId];
      }
      
      const result = await db.query(sql, params);
      return result[0].count;
    } catch (error) {
      console.error('获取未读消息数量错误:', error);
      throw error;
    }
  }

  /**
   * 撤回消息
   * @param {number} messageId 消息ID
   * @param {number} userId 用户ID
   * @returns {Promise<boolean>} 操作结果
   */
  static async recall(messageId, userId) {
    try {
      const sql = `
        UPDATE messages 
        SET is_recalled = 1, recalled_at = CURRENT_TIMESTAMP
        WHERE id = ? AND from_user_id = ?
        AND TIMESTAMPDIFF(MINUTE, created_at, CURRENT_TIMESTAMP) <= 2
      `;
      
      const result = await db.query(sql, [messageId, userId]);
      return result.affectedRows > 0;
    } catch (error) {
      console.error('撤回消息错误:', error);
      throw error;
    }
  }

  /**
   * 获取用户最近会话列表
   * @param {number} userId 用户ID
   * @param {number} limit 限制数量
   * @returns {Promise<Array>} 会话列表
   */
  static async getRecentConversations(userId, limit = 20) {
    try {
      // 简化查询，先返回空数组，避免复杂SQL导致的错误
      console.log('获取用户最近会话列表，用户ID:', userId)
      return []

      // TODO: 后续实现完整的会话列表查询
      /*
      const sql = `
        SELECT
          c.id as conversation_id,
          c.type,
          c.name as conversation_name
        FROM conversations c
        JOIN conversation_participants cp ON c.id = cp.conversation_id
        WHERE cp.user_id = ?
        AND cp.left_at IS NULL
        ORDER BY c.updated_at DESC
        LIMIT ?
      `;

      return await db.query(sql, [userId, limit]);
      */
    } catch (error) {
      console.error('获取最近会话列表错误:', error);
      return []
    }
  }
}

module.exports = Message;
